FrameLib  2.0
DSP processing with frames of arbitrary timing and length
FrameLib_Memory.h
Go to the documentation of this file.
1 
2 #ifndef FRAMELIB_MEMORY_H
3 #define FRAMELIB_MEMORY_H
4 
5 #include "../FrameLib_Dependencies/tlsf/tlsf.h"
6 #include "FrameLib_Types.h"
7 #include "FrameLib_Errors.h"
8 #include "FrameLib_Parameters.h"
9 #include "FrameLib_Threading.h"
10 
11 #include <vector>
12 #include <ctime>
13 #include <string>
14 
32 {
33 
34 private:
35 
44  class CoreAllocator
45  {
54  struct Pool
55  {
56  Pool(void *mem, size_t size) : mUsedRecently(true), mTime(0), mSize(size), mPrev(nullptr), mNext(nullptr), mMem(mem) {}
57 
58  bool isFree() { return tlsf_pool_is_free(mMem); }
59 
60  bool mUsedRecently;
61  time_t mTime;
62  size_t mSize;
63  Pool *mPrev;
64  Pool *mNext;
65  void *mMem;
66  };
67 
76  class NewThread final : public FrameLib_DelegateThread
77  {
78 
79  public:
80 
81  NewThread(CoreAllocator *allocator) : FrameLib_DelegateThread(FrameLib_Thread::kHighPriority), mAllocator(allocator) {}
82 
83  private:
84 
85  void doTask() override { mAllocator->addScheduledPool(); };
86 
87  CoreAllocator *mAllocator;
88  };
89 
98  class FreeThread final : public FrameLib_TriggerableThread
99  {
100 
101  public:
102 
103  FreeThread(CoreAllocator *allocator) : FrameLib_TriggerableThread(FrameLib_Thread::kLowPriority), mAllocator(allocator) {}
104 
105  private:
106 
107  void doTask() override { mAllocator->destroyScheduledPool(); };
108 
109  CoreAllocator *mAllocator;
110  };
111 
112  public:
113 
114  CoreAllocator(FrameLib_ErrorReporter& errorReporter);
115  ~CoreAllocator();
116 
117  // Allocate and deallocate memory (plus pruning)
118 
119  void *alloc(size_t size);
120  void dealloc(void *ptr);
121 
122  void prune();
123 
124  private:
125 
126  // Get a Pool Class a tlsf pool_t
127 
128  Pool *getPool(pool_t pool);
129 
130  // Pool Helpers
131 
132  static Pool *createPool(size_t size);
133  static void destroyPool(Pool *pool);
134  void linkPool(Pool *pool);
135  void unlinkPool(Pool *pool);
136  void poolToTop(Pool *pool);
137  void insertPool(Pool *pool);
138  void removePool(Pool *pool);
139 
140  // Scheduled creation/deletion
141 
142  void addScheduledPool();
143  void destroyScheduledPool();
144 
145  // Member Variables
146 
147  tlsf_t mTLSF;
148  Pool *mPools;
149 
150  size_t mOSAllocated;
151  size_t mAllocated;
152 
153  size_t mLastDisposedPoolSize;
154  std::atomic<Pool *> mScheduledNewPool;
155  std::atomic<Pool *> mScheduledDisposePool;
156  NewThread mAllocThread;
157  FreeThread mFreeThread;
158 
159  FrameLib_ErrorReporter& mErrorReporter;
160  };
161 
162 public:
163 
172  class Pruner
173  {
174 
175  public:
176 
177  Pruner(FrameLib_GlobalAllocator *allocator) : mAllocator(allocator)
178  {
179  mAllocator->mLock.acquire();
180  }
181 
183  {
184  mAllocator->mAllocator.prune();
185  mAllocator->mLock.release();
186  }
187 
188  // Non-copyable
189 
190  Pruner(const Pruner&) = delete;
191  Pruner& operator=(const Pruner&) = delete;
192 
193  void dealloc(void *ptr) { mAllocator->mAllocator.dealloc(ptr); }
194 
195  private:
196 
197  // Allocator
198 
199  FrameLib_GlobalAllocator *mAllocator;
200  };
201 
202  // ************************************************************************************** //
203 
204  // Constructor / Destructor
205 
206  FrameLib_GlobalAllocator(FrameLib_ErrorReporter& errorReporter) : mAllocator(errorReporter) {}
208 
209  // Non-copyable
210 
213 
214  // Allocate / Deallocate Memory
215 
216  void *alloc(size_t size);
217  void dealloc(void *ptr);
218 
219  // Alignment Helpers
220 
221  static size_t getAlignment();
222  static size_t alignSize(size_t x);
223 
224 private:
225 
226  // Member Variables
227 
228  FrameLib_SpinLock mLock;
229  CoreAllocator mAllocator;
230 };
231 
232 
246 {
247  static const int numLocalFreeBlocks = 16;
248 
257  struct FreeBlock
258  {
259  FreeBlock() : mMemory(nullptr), mSize(0), mPrev(nullptr), mNext(nullptr) {}
260 
261  void *mMemory;
262  size_t mSize;
263 
264  FreeBlock *mPrev;
265  FreeBlock *mNext;
266  };
267 
268 public:
269 
278  class Storage
279  {
281 
283 
284  public:
285 
294  class Access
295  {
296 
297  public:
298 
299  // Constructor and Destructor
300 
301  Access(Storage *storage) : mStorage(storage) { mStorage->mLock.acquire(); }
302  ~Access() { mStorage->mLock.release(); }
303 
304  // Non-copyable
305 
306  Access(const Access&) = delete;
307  Access& operator=(const Access&) = delete;
308 
309  // Getters
310 
311  FrameType getType() const { return mStorage->getType(); }
312  double *getVector() const { return mStorage->getVector(); }
313  unsigned long getVectorSize() const { return mStorage->getVectorSize(); }
314  unsigned long getTaggedSize() const { return mStorage->getTaggedSize(); }
315  Serial *getTagged() const { return mStorage->getTagged(); }
316 
317  // Resize
318 
319  void resize(bool tagged, size_t size) { mStorage->resize(tagged, size); }
320 
321  private:
322 
323  // Data
324 
325  Storage *mStorage;
326  };
327 
328  const char *getName() const { return mName.c_str(); }
329 
330  protected:
331 
332  // Getters
333 
334  FrameType getType() const { return mType; }
335  double *getVector() const { return mType == kFrameNormal ? static_cast<double *>(mData) : nullptr; }
336  unsigned long getVectorSize() const { return mType == kFrameNormal ? mSize : 0; }
337  unsigned long getTaggedSize() const { return mType == kFrameTagged ? mSize : 0; }
338  Serial *getTagged() const { return mType == kFrameTagged ? static_cast<Serial *>(mData) : nullptr; }
339 
340  // Resize the storage
341 
342  void resize(bool tagged, size_t size);
343 
344  // Constructor / Destructor
345 
346  Storage(const char *name, FrameLib_LocalAllocator *allocator);
347  ~Storage();
348 
349  // Non-copyable
350 
351  Storage(const Storage&) = delete;
352  Storage& operator=(const Storage&) = delete;
353 
354  // Reference Counting
355 
356  void increment() { mCount++; }
357  unsigned long decrement() { return --mCount; }
358 
359  private:
360 
361  // Member Variables
362 
363  std::string mName;
364  FrameType mType;
365  void *mData;
366  size_t mSize;
367  size_t mMaxSize;
368  unsigned long mCount;
369 
370  FrameLib_SpinLock mLock;
371  FrameLib_LocalAllocator *mAllocator;
372  };
373 
374  // Constructor / Destructor
375 
378 
379  // Non-copyable
380 
383 
384 
385  // Allocate / Deallocate Memory
386 
387  void *alloc(size_t size);
388  void dealloc(void *ptr);
389 
390  // Clear Local Free Blocks (and prune global allocator)
391 
392  void clear();
393 
394  // Alignment Helpers
395 
397  static size_t alignSize(size_t x) { return FrameLib_GlobalAllocator::alignSize(x); }
398 
399  // Register and Release Storage
400 
401  Storage *registerStorage(const char *name);
402  void releaseStorage(const char *name);
403 
404 private:
405 
406  // Find Storage by Name
407 
408  std::vector<Storage *>::iterator findStorage(const char *name);
409 
410  // Remove a Free Block after Allocation and Return the Pointer
411 
412  void *removeBlock(FreeBlock *block);
413 
414  // Member Variables
415 
416  FrameLib_GlobalAllocator *mAllocator;
417 
418  FreeBlock mFreeLists[numLocalFreeBlocks];
419  FreeBlock *mTail;
420 
421  std::vector<Storage *> mStorage;
422 };
423 
424 #endif
Pruner(FrameLib_GlobalAllocator *allocator)
Definition: FrameLib_Memory.h:177
~FrameLib_GlobalAllocator()
Definition: FrameLib_Memory.h:207
void resize(bool tagged, size_t size)
Definition: FrameLib_Memory.h:319
double * getVector() const
Definition: FrameLib_Memory.h:335
FrameLib_GlobalAllocator(FrameLib_ErrorReporter &errorReporter)
Definition: FrameLib_Memory.h:206
Definition: FrameLib_Types.h:54
static size_t getAlignment()
Definition: FrameLib_Memory.cpp:262
Serial * getTagged() const
Definition: FrameLib_Memory.h:338
a spinlock that can be locked, attempted or acquired.
Definition: FrameLib_Threading.h:84
a set of tagged parameter values using external non-owned memory.
Definition: FrameLib_Parameters.h:51
void dealloc(void *ptr)
Definition: FrameLib_Memory.cpp:254
const char * getName() const
Definition: FrameLib_Memory.h:328
a thread that can be triggered from another thread (there is no mechanism to check progress) ...
Definition: FrameLib_Threading.h:244
void increment()
Definition: FrameLib_Memory.h:356
a class used to report errors to the host environment.
Definition: FrameLib_Errors.h:34
Access(Storage *storage)
Definition: FrameLib_Memory.h:301
FrameLib_GlobalAllocator & operator=(const FrameLib_GlobalAllocator &)=delete
static size_t getAlignment()
Definition: FrameLib_Memory.h:396
Definition: FrameLib_Threading.h:161
void dealloc(void *ptr)
Definition: FrameLib_Memory.h:193
FrameType getType() const
Definition: FrameLib_Memory.h:311
unsigned long getVectorSize() const
Definition: FrameLib_Memory.h:336
~Access()
Definition: FrameLib_Memory.h:302
Definition: FrameLib_Types.h:54
~Pruner()
Definition: FrameLib_Memory.h:182
void * alloc(size_t size)
Definition: FrameLib_Memory.cpp:248
an RAII utility for safely accessing a Storage object.
Definition: FrameLib_Memory.h:294
a global threadsafe memory allocator suitable for realtime usage.
Definition: FrameLib_Memory.h:31
static size_t alignSize(size_t x)
Definition: FrameLib_Memory.h:397
a memory allocator suitable for usage in a given FrameLib context.
Definition: FrameLib_Memory.h:245
static size_t alignSize(size_t x)
Definition: FrameLib_Memory.cpp:267
unsigned long decrement()
Definition: FrameLib_Memory.h:357
FrameType
Definition: FrameLib_Types.h:54
named storage local to a specific context.
Definition: FrameLib_Memory.h:278
double * getVector() const
Definition: FrameLib_Memory.h:312
Serial * getTagged() const
Definition: FrameLib_Memory.h:315
Definition: FrameLib_Threading.h:161
an RAII utility for repeated deallocation with only a single lock.
Definition: FrameLib_Memory.h:172
a thread to delegate tasks to, which can be then be checked for completion
Definition: FrameLib_Threading.h:296
unsigned long getVectorSize() const
Definition: FrameLib_Memory.h:313
unsigned long getTaggedSize() const
Definition: FrameLib_Memory.h:314
FrameType getType() const
Definition: FrameLib_Memory.h:334
unsigned long getTaggedSize() const
Definition: FrameLib_Memory.h:337